package com.yx.backstage.security.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yx.backstage.config.global.BizException;
import com.yx.backstage.config.global.CommonResult;
import com.yx.backstage.model.SysUser;
import com.yx.backstage.model.param.SysUserParam;
import com.yx.backstage.security.LoginUser;
import com.yx.backstage.security.service.LoginService;
import com.yx.backstage.service.SysUserService;
import com.yx.backstage.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author YangXiong
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private SysUserService sysUserService;

    @Override
    public CommonResult<HashMap<String, String>> login(SysUserParam sysUser) {
        //判断验证码是否正确
        String code = sysUser.getCode();
        String uuid = sysUser.getUuid();
        String key = redisTemplate.opsForValue().get(uuid);
        if(Objects.isNull(key)){
            throw new BizException("验证码过期");
        }
        if (!Objects.equals(code.toLowerCase(), key)) {
            throw new BizException("验证码错误");
        }
        Authentication authentication;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(sysUser.getAccount(), sysUser.getPassword());
            authentication = authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
        if (Objects.isNull(authentication)) {
            throw new BizException("登录失败");
        }
        LoginUser user = (LoginUser) authentication.getPrincipal();
        SysUser returnUser = user.getSysUser();
        String token = JwtUtil.createJwt(returnUser.getId().toString());
        HashMap<String, String> map = new HashMap<>(4);
        map.put("token", token);
        map.put("userName", returnUser.getUserName());
        map.put("avatar", returnUser.getAvatar());
        //写入缓存
        Long userId = returnUser.getId();
        redisTemplate.opsForValue().set("login:" + userId, JSON.toJSONString(user), 10, TimeUnit.MINUTES);
        //更新登录时间
        LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<SysUser>().eq(SysUser::getId, returnUser.getId())
                .set(SysUser::getLastLoginTime, DateUtil.date());
        sysUserService.update(wrapper);
        return CommonResult.success(map);
    }

    @Override
    public CommonResult<String> logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long userId = loginUser.getSysUser().getId();
        redisTemplate.delete("login:" + userId);
        return CommonResult.success("注销成功");
    }
}
